package com.kun.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kun.common.file.minio.MinioTemplate;
import com.kun.dto.SysFileDTO;
import com.kun.dto.SysFileDelMoveDTO;
import com.kun.entity.SysFile;
import com.kun.entity.SysFileStorage;
import com.kun.mapper.FileStorageMapper;
import com.kun.mapper.SysFileMapper;
import com.kun.service.SysFileService;
import com.kun.util.ResponseResult;
import io.minio.ObjectWriteResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.List;

/**
 * @author kun.li
 */
@Service
@Slf4j
public class SysFileServiceImpl extends ServiceImpl<SysFileMapper, SysFile> implements SysFileService {

    @Autowired
    private SysFileMapper sysFileMapper;

    @Autowired
    private FileStorageMapper fileStorageMapper;

    @Autowired
    private MinioTemplate minioTemplate;

    @Override
    public void deleteFile(SysFileDelMoveDTO sysFileDelDTO) {
        SysFileStorage sysFileStorage = fileStorageMapper.selectById(sysFileDelDTO.getStorageId());
        String storageDirectory = sysFileStorage.getStorageAbsoluteDirectory();
        List<SysFile> sysFiles = sysFileMapper.selectList(Wrappers.<SysFile>lambdaQuery().in(SysFile::getFileId, sysFileDelDTO.getFileIds()));
        for (SysFile sysFile : sysFiles) {
            // 删除文件
            storageDirectory = storageDirectory + sysFile.getFileFullName();
            try {
                minioTemplate.removeObject(storageDirectory);
                sysFileMapper.deleteById(sysFile);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }

    @Override
    public String saveFile(SysFileDTO sysFileDTO) {
        String storageId = sysFileDTO.getStorageId();
        SysFileStorage sysFileStorage = fileStorageMapper.selectById(storageId);
        // 获取到文件要存储的目录
        String storageDirectory = sysFileStorage.getStorageAbsoluteDirectory();
        if (StrUtil.isEmpty(storageDirectory)) {
            return "没有找到要存储的目录";
        }
        // 获取文件的原始名称
        MultipartFile file = sysFileDTO.getFile();
        String originalFilename = file.getOriginalFilename();
        // 文件的后缀
        String extName = FileUtil.extName(originalFilename);
        // 获取文件名称
        String prefixName = FileUtil.getPrefix(originalFilename);
        String fileAbsolutePath = storageDirectory + originalFilename;
        try (InputStream inputStream = file.getInputStream()) {
            // 上传到minio之前需要先检查文件是否存在
            if (minioTemplate.checkBuckFileExist(fileAbsolutePath)) {
                return "不要重复上传同名文件";
            }
            minioTemplate.fileUpload(fileAbsolutePath, inputStream, file.getSize(), file.getContentType());
            // 新增文件
            SysFile sysFile = new SysFile();
            sysFile.setFileFullName(originalFilename);
            sysFile.setFileType(extName);
            sysFile.setStorageId(storageId);
            sysFile.setFileName(prefixName);
            sysFile.setFileFullPath(minioTemplate.buildMinioAddress() + "/" + fileAbsolutePath);
            sysFileMapper.insert(sysFile);
        } catch (Exception e) {
            // 文件上传失败
            return "文件上传失败";
        }
        return "处理成功";
    }

    @Override
    public Boolean updateFile(SysFile sysFile) {
        return sysFileMapper.updateById(sysFile) > 0;
    }

    @Override
    public ResponseResult moveFile(SysFileDelMoveDTO sysFileMoveDTO) {
        List<SysFile> sysFileList = sysFileMapper.selectList(Wrappers.<SysFile>lambdaQuery().in(SysFile::getFileId, sysFileMoveDTO.getFileIds()));
        String newStorageId = sysFileMoveDTO.getStorageId();
        for (SysFile sysFile : sysFileList) {
            String fileFullName = sysFile.getFileFullName();
            SysFileStorage fileStorage = fileStorageMapper.selectById(sysFile.getStorageId());
            String sourceAbsoluteDirectory = fileStorage.getStorageAbsoluteDirectory() + fileFullName;
            SysFileStorage sysFileStorage = fileStorageMapper.selectById(newStorageId);
            String newDirectory = sysFileStorage.getStorageAbsoluteDirectory();
            String targetAbsoluteDirectory = newDirectory + fileFullName;
            try {
                ObjectWriteResponse objectWriteResponse = minioTemplate.copyFile(sourceAbsoluteDirectory, targetAbsoluteDirectory);
                minioTemplate.removeObject(sourceAbsoluteDirectory);
                // 修改文件目录
                sysFile.setFileFullPath(minioTemplate.buildMinioAddress() + "/" + objectWriteResponse.object());
                sysFile.setStorageId(newStorageId);
                sysFileMapper.updateById(sysFile);
            } catch (Exception e) {
                log.error("文件移动失败", e);
                return ResponseResult.failed("文件移动失败");
            }
        }
        return ResponseResult.success();
    }
}
